package edu.dillo.dillotude;

import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import edu.dillo.dillotude.DilloTude.GameStates;

public class LevelState extends BasicGameState {

	private Level loadedLevel;
	private Player Armadillo;
	private SpriteSheet blockSprites;
	private int elaspedTime;
	private int health = 2;
	private Image healthbar;
	public LevelState() throws SlickException
	{
		loadedLevel = new Level();
		elaspedTime = 0;
	}
	
	public LevelState(Level lvl)throws SlickException
	{
		setLoadedLevel(lvl);
		elaspedTime = 0;
	}

	@Override
	public void init(GameContainer arg0, StateBasedGame arg1)
			throws SlickException {
		
		
		//------------------------Level loading-------------------------------------------------------
		blockSprites = new SpriteSheet(new Image("/media/player_sprites/dirt_blocks.png"), 100,100);// Loading the sprite sheet for the blocks
		loadedLevel.setBlocks(readBlocksFromFile("long_test"));// Setting the level's block array based on the level builder output
		//--------------------------------------------------------------------------------------------		
		
		Dimension[] dilloAnimDims = {new Dimension(140,190),new Dimension(140,150),new Dimension(130,190),new Dimension(160,160),new Dimension(150,190),new Dimension(150,160),new Dimension(160,160)};
		Dimension[] dilloFrameDims = {new Dimension(7,2), new Dimension(7,3),new Dimension(7,2), new Dimension(6,3),new Dimension(3,2), new Dimension(6,2), new Dimension(6,3)};
		int[] dilloLastRowLengths = {2,2,5,2,2,3,4};
		int[] dilloAnimSpeeds = {50,50,50,300,50,50,50};
		String[] dilloAnimNames = {"apex", "fall","fly", "idle","jump", "land", "running"};
		
		Armadillo = new Player(300,300,145);
		Armadillo.addAnimation("media/player_sprites/dillo-anims", dilloAnimDims, dilloFrameDims, dilloAnimSpeeds, dilloLastRowLengths, dilloAnimNames);
		Armadillo.setActiveAnimationKey("idle");
		healthbar = new Image("/media/Health 100.png");
		
		
		/*
		Music bgm = new Music("/media/music/islands.wav");
		bgm.loop();
		*/

	}

	@Override
	public void render(GameContainer arg0, StateBasedGame arg1, Graphics g)
			throws SlickException {
		if (loadedLevel.getBackground() != null)
			g.drawImage(loadedLevel.getBackground(), 0, 0);
		g.setWorldClip(0,0,1000,500);
		g.translate(Armadillo.getCameraPosititionX(), Armadillo.getCameraPositionY());
		loadedLevel.render(arg0, arg1, g);
		Armadillo.render(arg0, arg1, g);
		g.drawString("Time: " + totalTime(timeInSec(elaspedTime)), 750 - Armadillo.getCameraPosititionX(),-Armadillo.getCameraPositionY() + 10);
		g.drawImage(healthbar,750 - Armadillo.getCameraPosititionX(), 50-Armadillo.getCameraPositionY());
	
	}

	@Override
	public void update(GameContainer arg0, StateBasedGame arg1, int arg2)
			throws SlickException {
		
		Armadillo.update(arg0, arg1, 0, loadedLevel.getBlocks());
		elaspedTime += arg2;
		healthBar(health);
	
	}

	@Override
	public int getID() {
		return GameStates.LEVEL_STATE.ordinal();
	}
	
	public Level getLoadedLevel()
	{
		return loadedLevel;
	}
	
	public void setLoadedLevel(Level lvl)
	{
		loadedLevel = lvl;
	}
	
	public GridBlock[][] readBlocksFromFile(String path) throws SlickException
	{
		FileReader fr;
		BufferedReader br;
		int ysize = 0, xsize = 0;
		String currentline;
		// Determining the size of the block array based on the input file
		try {
			fr = new FileReader(path);
			br = new BufferedReader(fr);
			currentline = br.readLine();
			String[] temp = currentline.split(" ");
			xsize = temp.length;
			while (currentline != null)
			{
				currentline = br.readLine();
				ysize++;
			}
			fr.close();
			br.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		GridBlock[][] Blocks = new GridBlock[ysize][xsize];
		
		
		String[][] grid = new String[ysize][xsize];
		
		try{
			fr = new FileReader(path);
		    br = new BufferedReader(fr);
			
			for (int i = 0; i < ysize; i++)
			{
				grid[i] = br.readLine().split(" ");
			}	
			br.close();
		}catch (IOException e){
			e.printStackTrace();
		}
		
		for (int i = 0; i < ysize; i++)
		{
			for (int j = 0; j < xsize; j++)
			{
				Blocks[i][j] = new GridBlock(100*j,100*i,100,false,blockSprites);
				Blocks[i][j].setRelativeX(j);
				Blocks[i][j].setRelativeY(i);
				switch (grid[i][j])
				{
				case "Z":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.NONE);
					Blocks[i][j].setCollidable(false);
					break;
				case "X":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_NONE);
					Blocks[i][j].setCollidable(true);
					break;
				case "T":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_TOP);
					Blocks[i][j].setCollidable(true);
					break;
				case "S":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_SIDE);
					Blocks[i][j].setCollidable(true);
					break;
				case "TS":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_TOP_SIDE);
					Blocks[i][j].setCollidable(true);
					break;
				case "CP":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_CORNER_PAD);
					Blocks[i][j].setCollidable(false);
					break;
				case "GT":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_TAPERED);
					Blocks[i][j].setCollidable(true);
					break;
				case "S'":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_SIDE_F);
					Blocks[i][j].setCollidable(true);
					break;
				case "TS'":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_TOP_SIDE_F);
					Blocks[i][j].setCollidable(true);
					break;
				case "CP'":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_CORNER_PAD_F);
					Blocks[i][j].setCollidable(false);
					break;
				case "GT'":
					Blocks[i][j].setBlockImage(GridBlock.BlockType.GRASS_TAPERED_F);
					Blocks[i][j].setCollidable(true);
					break;
				default:
					Blocks[i][j].setBlockImage(GridBlock.BlockType.NONE);
					Blocks[i][j].setCollidable(false);	
					break;
				}
					
			}
			
		}
		return Blocks;
	}
		



public int timeInSec (int time) // Converts the total elasped time from milliseconds to seconds (in an integer) 
{

	int temp = time/1000;
	
	return temp;	
}

public String totalTime (int totalSec) // Converts the total elasped time from seconds, to hour, minute, second format and creates a string using these values
{
	int hour, min, sec;
	String time;
	hour = totalSec / 3600;
	totalSec -= hour * 3600;
	min = totalSec / 60;
	totalSec -= min * 60;
	sec = totalSec;
	if (hour != 0)
	{
		 time = hour + " h, " + min + " m, " + sec + " s";
	}
	else
	{
		if (min != 0)
		{
			 time = min + " m, " + sec + " s";
		}
		else
		{
			 time = sec + " s";
		}
	}
	
	return time;
}

public void healthBar(int health) throws SlickException
{
	switch(health)
	{
	case 0: healthbar = new Image("/media/Health 0.png");
	break;
	case 1: healthbar = new Image("/media/Health 50.png");
	break;
	case 2: healthbar = new Image("/media/Health 100.png");
	break;
	}

}

public void setHealth(int playerHealth) throws SlickException
{
	health = playerHealth;
}

public int getHealth()
{
	return health;
}

}
